
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.validators import ASCIIUsernameValidator
from django.conf import settings
from django.db import models

# Create your models here.


class AdminUserManager(BaseUserManager):
    def _create_user(self, username, password, **extra_fields):
        if not username:
            raise ValueError('The given username must be set')
        username = self.model.normalize_username(username)
        user = self.model(username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, username, password=None, **extra_fields):
        """系统管理员和用户管理员是内置的，只能创建审计管理员"""
        extra_fields.setdefault('admin_level', AdminUser.AUDIT_ADMIN)
        return self._create_user(username, password, **extra_fields)

    def create_superuser(self, username, password, **extra_fields):
        """Every user in this model is an admin, so two methods are exactly the same"""
        return self.create_user(username, password, **extra_fields)


class AdminUser(AbstractBaseUser):
    """管理员账户表，控制系统访问权限"""
    objects = AdminUserManager()

    username = models.CharField(
        unique=True, max_length=256,
        validators=[ASCIIUsernameValidator()],
        error_messages={
            'null': '用户名不能为空。',
            'blank': '用户名不能为空。',
            'invalid': '输入的用户名无效。用户名只能由大小写字母、数字、下划线以及@构成。',
            'unique': '此用户名已存在。请更换其他用户名。',
        }
    )

    SYSTEM_ADMIN = 0
    SYSTEM_ADMIN_USERNAME = 'sysadmin'
    SYSTEM_ADMIN_NAME = '系统管理员'
    ACCOUNT_ADMIN = 1
    ACCOUNT_ADMIN_USERNAME = 'useradmin'
    ACCOUNT_ADMIN_NAME = '用户管理员'
    AUDIT_ADMIN = 2
    AUDIT_ADMIN_NAME = '审计管理员'
    STRATEGY_ADMIN = 3
    STRATEGY_ADMIN_NAME = '安全管理员'
    ADMIN_LEVELS = (
        (SYSTEM_ADMIN, SYSTEM_ADMIN_NAME),
        (ACCOUNT_ADMIN, ACCOUNT_ADMIN_NAME),
        (AUDIT_ADMIN, AUDIT_ADMIN_NAME),
        (STRATEGY_ADMIN, STRATEGY_ADMIN_NAME),
    )

    admin_level = models.PositiveSmallIntegerField(
        choices=ADMIN_LEVELS
    )
    related_user = models.OneToOneField(            # 安全管理员账户关联的网关账户
        'zmad.ZTPUser',
        on_delete=models.CASCADE,
        related_name='admin_user',
        null=True  # 系统管理员和用户管理员没有关联的网关账户
    )
    is_active = models.BooleanField(default=True)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['admin_level']

    class Meta:
        managed = False
        db_table = '"zmad"."admin_user"'

    def set_password(self, raw_password):
        """不要调用此方法，这个方法是ZTPUser重置密码时使用的"""
        self.password = make_password(raw_password, hasher=settings.PASSWORD_ALGORITHM)
        self._password = raw_password
